/*
 * ImPduClient.h
 *
 *  Created on: 2013-8-27
 *      Author: ziteng@mogujie.com
 */

#ifndef IMPDUCLIENT_H_
#define IMPDUCLIENT_H_

#include "ImPduBase.h"
#include <list>
using namespace std;

#define IM_PDU_LOGIN_REQ                        1
#define IM_PDU_LOGIN_RES                        2
#define IM_PDU_INIT_CALL_REQ                    3
#define IM_PDU_INIT_CALL_RES                    4
#define IM_PDU_CALL_NOTIFY_REQ                  5
#define IM_PDU_CALL_NOTIFY_RES                  6
#define IM_PDU_HUNG_UP_REQ                      7
#define IM_PDU_HUNG_UP_RES                      8
#define IM_PDU_HUNG_NOTIFY_REQ                  9
#define IM_PDU_HUNG_NOTIFY_RES                  10
#define IM_PDU_ONLINE_USER_REQ                  11
#define IM_PDU_ONLINE_USER_RES                  12

enum {
	CLIENT_TYPE_UNKNOWN		= 0,
	CLIENT_TYPE_WIN 		= 1,
	CLIENT_TYPE_MAC			= 2,
	CLIENT_TYPE_ANDROID		= 3,
	CLIENT_TYPE_IOS			= 4
};

/*
 * 登录请求
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 登录请求为:1
 * reversed:    uint16 保留字段，默认填写0
 * user_id:     uint32 用户ID
 * client_type: uint16 终端类型,枚举值如下:
 * enum {
 *	CLIENT_TYPE_UNKNOWN		= 0,
 *	CLIENT_TYPE_WIN 		= 1,
 *	CLIENT_TYPE_MAC			= 2,
 *	CLIENT_TYPE_ANDROID		= 3,
 *	CLIENT_TYPE_IOS			= 4
 * };
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +--------------------------------+----------------+----------------+
 * Body    | user_id                        | client_type    |
 *         +--------------------------------+----------------+
 *
 */

class CImPduLoginReq:public CImPdu {
public:
    CImPduLoginReq(uchar_t* pBuf, uint32_t nLen);
    CImPduLoginReq(uint32_t nUserId,uint16_t nClientType);
    virtual ~CImPduLoginReq();
    
    
    virtual uint16_t getPduType() { return IM_PDU_LOGIN_REQ; }
    
    uint32_t getUserId() { return m_nUserId; }
    uint32_t getClientType() { return m_nClientType; }
private:
    uint32_t m_nUserId;
    uint16_t m_nClientType;
};

/*
 * 登录返回
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 登录返回为:2
 * reversed:    uint16 保留字段，默认填写0
 * status:      uint16 标志返回成功与否，成功返回0，否则返回失败
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | status         |
 *         +----------------+
 *
 */

class CImPduLoginRes:public CImPdu  {
public:
    CImPduLoginRes(uchar_t* pBuf, uint32_t nLen);
    CImPduLoginRes(uint16_t nStatus);
    virtual ~CImPduLoginRes();
    
    virtual uint16_t getPduType() { return IM_PDU_LOGIN_RES; }
    
    uint16_t getStatus() { return m_nStatus; }
private:
    uint16_t m_nStatus;
};

/*
 * 发起呼叫
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 发起呼叫为:3
 * reversed:    uint16 保留字段，默认填写0
 * to_id:       uint32 对方id
 * call_id:     uint32 通话id
 * body_len:    uint32 body的长度
 * body:        char*  body
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | to_id                          | call_id                         |
 *         +--------------------------------+---------------------------------+
 *         | body_len                       | body ...                         
 *         +--------------------------------+---------------------------------+
 *
 */

class CImPduInitCallReq:public CImPdu  {
public:
    CImPduInitCallReq(uchar_t* pBuf, uint32_t nLen);
    CImPduInitCallReq(uint32_t nToId, uint32_t nCallId,const char* pBody, uint32_t nLen);
    virtual ~CImPduInitCallReq();
    
    virtual uint16_t getPduType() { return IM_PDU_INIT_CALL_REQ; }
    
    uint32_t getToId() { return m_nToId; }
    uint32_t getCallId() { return m_nCallId; }
    string& getBody() { return m_strBody;}
    
private:
    uint32_t m_nToId;
    uint32_t m_nCallId;
    string m_strBody;
};

/*
 * 发起呼叫回应
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 发起呼叫回应为:4
 * reversed:    uint16 保留字段，默认填写0
 * to_id:       uint32 对方id
 * call_id:     uint32 呼叫id
 * code:        uint16 返回码
 * reason_len:  uint32 返回消息长度
 * reason:      string 返回消息
 * body_len:    uint32 body的长度
 * body:        char*  body
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | to_id                          | call_id                         |
 *         +--------------------------------+---------------------------------+
 *         | code           | reason_len                     | reason ...
 *         +----------------+--------------------------------+----------------+
 *         | body_len                       | body ...
 *         +--------------------------------+---------------------------------+
 */

class CImPduInitCallRes:public CImPdu  {
public:
    CImPduInitCallRes(uchar_t* pBuf, uint32_t nLen);
    CImPduInitCallRes(uint32_t nToId, uint32_t nCallId, uint16_t nCode, const string& strReason,const char* pBody, uint32_t nLen);
    virtual ~CImPduInitCallRes();
    
    virtual uint16_t getPduType() { return IM_PDU_INIT_CALL_RES; }
    
    uint32_t getToId() { return m_nToId; }
    uint32_t getCallId() { return m_nCallId; }
    uint16_t getCode() { return m_nCode; }
    string& getReason() { return m_strReason; }
    string& getBody() { return m_strBody;}
    
private:
    uint32_t m_nToId;
    uint32_t m_nCallId;
    uint16_t m_nCode;
    string m_strReason;
    string m_strBody;
};



/*
 * 发起呼叫通知
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 发起呼叫通知为:5
 * reversed:    uint16 保留字段，默认填写0
 * from_id:     uint32 呼叫发起方id
 * call_id:     uint32 呼叫id
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | from_id                        | call_id                         |
 *         +--------------------------------+---------------------------------+
 *         | body_len                       | body ...
 *         +--------------------------------+---------------------------------+
 *
 */

class CImPduCallNotifyReq:public CImPdu  {
public:
    CImPduCallNotifyReq(uchar_t* pBuf, uint32_t nLen);
    CImPduCallNotifyReq(uint32_t nFromId, uint32_t nCallId,const char* pBody, uint32_t nLen);
    virtual ~CImPduCallNotifyReq();
    
    virtual uint16_t getPduType() { return IM_PDU_CALL_NOTIFY_REQ; }
    
    uint32_t getFromId() { return m_nFromId; }
    uint32_t getCallId() { return m_nCallId; }
    string& getBody() { return m_strBody;}
    
private:
    uint32_t m_nFromId;
    uint32_t m_nCallId;
    string m_strBody;
};

/*
 * 发起呼叫通知回应
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 发起呼叫通知回应为:6
 * reversed:    uint16 保留字段，默认填写0
 * from_id:     uint32 呼叫发起方id
 * call_id:     uint32 呼叫id
 * code:        uint16 返回码
 * reason_len:  uint32 返回消息长度
 * reason:      string 返回消息
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | from_id                        | call_id                         |
 *         +--------------------------------+---------------------------------+
 *         | code           | reason_len                     | reason ...
 *         +----------------+--------------------------------+----------------+
 *         | body_len                       | body ...
 *         +--------------------------------+---------------------------------+
 */

class CImPduCallNotifyRes:public CImPdu  {
public:
    CImPduCallNotifyRes(uchar_t* pBuf, uint32_t nLen);
    CImPduCallNotifyRes(uint32_t nFromId, uint32_t nCallId, uint16_t nCode, const string& strReason,const char* pBody, uint32_t nLen);
    virtual ~CImPduCallNotifyRes();
    
    virtual uint16_t getPduType() { return IM_PDU_INIT_CALL_RES; }
    
    uint32_t getFromId() { return m_nFromId; }
    uint32_t getCallId() { return m_nCallId; }
    uint16_t getCode() { return m_nCode; }
    string& getReason() { return m_strReason; }
    string& getBody() { return m_strBody;}
    
private:
    uint32_t m_nFromId;
    uint32_t m_nCallId;
    uint16_t m_nCode;
    string m_strReason;
    string m_strBody;
};

/*
 * 挂断请求
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 挂断请求为:7
 * reversed:    uint16 保留字段，默认填写0
 * peer_id:     uint32 对方id(在这里是被挂断方id)
 * call_id:     uint32 呼叫id
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | peer_id                        | call_id                         |
 *         +--------------------------------+---------------------------------+
 */

class CImPduHungUpReq:public CImPdu {
public:
    CImPduHungUpReq(uchar_t* pBuf, uint32_t nLen);
    CImPduHungUpReq(uint32_t nPeerId, uint32_t nCallId);
    virtual ~CImPduHungUpReq();
    
    virtual uint16_t getPduType() { return IM_PDU_HUNG_UP_REQ; }
    
    uint32_t getPeerId() { return m_nPeerId; }
    uint32_t getCallId() { return m_nCallId; }
        
private:
    uint32_t m_nPeerId;
    uint32_t m_nCallId;
};

/*
 * 挂断请求回应
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 挂断请求回应为:8
 * reversed:    uint16 保留字段，默认填写0
 * peer_id:     uint32 对方id(在这里是被挂断方id)
 * call_id:     uint32 呼叫id
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | peer_id                        | call_id                         |
 *         +--------------------------------+---------------------------------+
 */

class CImPduHungUpRes:public CImPdu {
public:
    CImPduHungUpRes(uchar_t* pBuf, uint32_t nLen);
    CImPduHungUpRes(uint32_t nPeerId, uint32_t nCallId);
    virtual ~CImPduHungUpRes();
    
    virtual uint16_t getPduType() { return IM_PDU_HUNG_UP_RES; }
    
    uint32_t getPeerId() { return m_nPeerId; }
    uint32_t getCallId() { return m_nCallId; }
    
private:
    uint32_t m_nPeerId;
    uint32_t m_nCallId;
};

/*
 * 挂断请求通知
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 挂断请求通知为:9
 * reversed:    uint16 保留字段，默认填写0
 * peer_id:     uint32 对方id(在这里是挂断发起方id)
 * call_id:     uint32 呼叫id
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | peer_id                        | call_id                         |
 *         +--------------------------------+---------------------------------+
 */

class CImPduHungUpNotifyReq:public CImPdu {
public:
    CImPduHungUpNotifyReq(uchar_t* pBuf, uint32_t nLen);
    CImPduHungUpNotifyReq(uint32_t nPeerId, uint32_t nCallId);
    virtual ~CImPduHungUpNotifyReq();
    
    virtual uint16_t getPduType() { return IM_PDU_HUNG_UP_REQ; }
    
    uint32_t getPeerId() { return m_nPeerId; }
    uint32_t getCallId() { return m_nCallId; }
    
private:
    uint32_t m_nPeerId;
    uint32_t m_nCallId;
};

/*
 * 挂断请求通知回应
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 挂断请求通知回应为:10
 * reversed:    uint16 保留字段，默认填写0
 * peer_id:     uint32 对方id(这里是挂断发起方id)
 * call_id:     uint32 呼叫id
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | peer_id                        | call_id                         |
 *         +--------------------------------+---------------------------------+
 */

class CImPduHungUpNotifyRes:public CImPdu {
public:
    CImPduHungUpNotifyRes(uchar_t* pBuf, uint32_t nLen);
    CImPduHungUpNotifyRes(uint32_t nPeerId, uint32_t nCallId);
    virtual ~CImPduHungUpNotifyRes();
    
    virtual uint16_t getPduType() { return IM_PDU_HUNG_UP_RES; }
    
    uint32_t getPeerId() { return m_nPeerId; }
    uint32_t getCallId() { return m_nCallId; }
    
private:
    uint32_t m_nPeerId;
    uint32_t m_nCallId;
};


/*
 * 获取在线用户请求
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 挂断请求通知为:11
 * reversed:    uint16 保留字段，默认填写0
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    ||
 *
 */

class CImPduOnlineUserReq:public CImPdu {
public:
    CImPduOnlineUserReq(uchar_t* pBuf, uint32_t nLen);
    CImPduOnlineUserReq();
    virtual ~CImPduOnlineUserReq();
    
    virtual uint16_t getPduType() { return IM_PDU_ONLINE_USER_REQ; }
};

/*
 * 获取在线用户回复
 * length:      uint32 包长度(包含包头长度,包头固定8字节)
 * cmd_id:      uint16 命令号 挂断请求通知回应为:10
 * reversed:    uint16 保留字段，默认填写0
 * user_cnt     uint32 在线用户数
 * user_id1     uint32 第一个user_id  \
 * user_id2     uint32 第二个user_id  | user_id list
 * ...                               /
 *
 *
 *         |<----  2B  ---->|<---- 2B  ---->|<----  2B  ---->|<----  2B  ---->|
 *         +--------------------------------+----------------+----------------+
 * Header  | length                         |  cmd_id        |     reversed   |
 *         +----------------+---------------+----------------+----------------+
 * Body    | user_cnt                       | user_id1                        |
 *         +--------------------------------+---------------------------------+
 *         | user_id2                       | ...                             |
 *         +--------------------------------+---------------------------------+
 */

class CImPduOnlineUserRes:public CImPdu {
public:
    CImPduOnlineUserRes(uchar_t* pBuf, uint32_t nLen);
    CImPduOnlineUserRes(uint32_t nUserCnt, const list<uint32_t>& lsUsers);
    virtual ~CImPduOnlineUserRes();
    
    virtual uint16_t getPduType() { return IM_PDU_ONLINE_USER_RES; }
    
    uint32_t getOnlineUserCnt() { return m_nUserCnt; }
    list<uint32_t>& getOnlieUsers() { return m_lsUsers; }
    
private:
    uint32_t m_nUserCnt;
    list<uint32_t> m_lsUsers;
};



#endif /* IMPDUCLIENT_H_ */
